package com.gitee.wsl.android.ext.device

//package com.blankj.utilcode.util

import android.content.Context
import android.content.Intent
import android.media.AudioManager
import android.media.AudioManager.OnAudioFocusChangeListener
import android.os.Build
import android.provider.Settings
import com.gitee.wsl.android.ext.ApplicationInit.application
import com.gitee.wsl.android.ext.startForActivity
import com.gitee.wsl.android.notification.notificationManager
import timber.log.Timber


object VolumeExt {

    /**
     * Return the volume.
     *
     * @param streamType The stream type.
     *
     *  * [AudioManager.STREAM_VOICE_CALL]
     *  * [AudioManager.STREAM_SYSTEM]
     *  * [AudioManager.STREAM_RING]
     *  * [AudioManager.STREAM_MUSIC]
     *  * [AudioManager.STREAM_ALARM]
     *  * [AudioManager.STREAM_NOTIFICATION]
     *  * [AudioManager.STREAM_DTMF]
     *  * [AudioManager.STREAM_ACCESSIBILITY]
     *
     * @return the volume
     */
    fun getVolume(streamType: Int): Int {
        return application.audioManager.getStreamVolume(streamType)
    }

    /**
     * Sets media volume.<br></br>
     * When setting the value of parameter 'volume' greater than the maximum value of the media volume will not either cause error or throw exception but maximize the media volume.<br></br>
     * Setting the value of volume lower than 0 will minimize the media volume.
     *
     * @param streamType The stream type.
     *
     *  * [AudioManager.STREAM_VOICE_CALL]
     *  * [AudioManager.STREAM_SYSTEM]
     *  * [AudioManager.STREAM_RING]
     *  * [AudioManager.STREAM_MUSIC]
     *  * [AudioManager.STREAM_ALARM]
     *  * [AudioManager.STREAM_NOTIFICATION]
     *  * [AudioManager.STREAM_DTMF]
     *  * [AudioManager.STREAM_ACCESSIBILITY]
     *
     * @param volume     The volume.
     * @param flags      The flags.
     *
     *  * [AudioManager.FLAG_SHOW_UI]
     *  * [AudioManager.FLAG_ALLOW_RINGER_MODES]
     *  * [AudioManager.FLAG_PLAY_SOUND]
     *  * [AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE]
     *  * [AudioManager.FLAG_VIBRATE]
     *
     */
    fun setVolume(streamType: Int, volume: Int, flags: Int) {
        try {
            application.audioManager.setStreamVolume(streamType, volume, flags)
        } catch (ignore: SecurityException) {
             Timber.d(ignore)
        }
    }

    /**
     * Return the maximum volume.
     *
     * @param streamType The stream type.
     *
     *  * [AudioManager.STREAM_VOICE_CALL]
     *  * [AudioManager.STREAM_SYSTEM]
     *  * [AudioManager.STREAM_RING]
     *  * [AudioManager.STREAM_MUSIC]
     *  * [AudioManager.STREAM_ALARM]
     *  * [AudioManager.STREAM_NOTIFICATION]
     *  * [AudioManager.STREAM_DTMF]
     *  * [AudioManager.STREAM_ACCESSIBILITY]
     *
     * @return the maximum volume
     */
    fun getMaxVolume(streamType: Int): Int {
        return application.audioManager.getStreamMaxVolume(streamType)
    }

    /**
     * Return the minimum volume.
     *
     * @param streamType The stream type.
     *
     *  * [AudioManager.STREAM_VOICE_CALL]
     *  * [AudioManager.STREAM_SYSTEM]
     *  * [AudioManager.STREAM_RING]
     *  * [AudioManager.STREAM_MUSIC]
     *  * [AudioManager.STREAM_ALARM]
     *  * [AudioManager.STREAM_NOTIFICATION]
     *  * [AudioManager.STREAM_DTMF]
     *  * [AudioManager.STREAM_ACCESSIBILITY]
     *
     * @return the minimum volume
     */
    fun getMinVolume(streamType: Int): Int {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            application.audioManager.getStreamMinVolume(streamType)
        } else 0
    }


    // ==========
    // = 静音状态 =
    // ==========
    /**
     * 设置媒体声音静音状态
     * @param state `true` 静音, `false` 非静音
     * @return `true` success, `false` fail
     */
    fun setStreamMuteByMusic(state: Boolean): Boolean {
        return setStreamMute(AudioManager.STREAM_MUSIC, state)
    }

    /**
     * 设置通话声音静音状态
     * @param state `true` 静音, `false` 非静音
     * @return `true` success, `false` fail
     */
    fun setStreamMuteByVoiceCall(state: Boolean): Boolean {
        return setStreamMute(AudioManager.STREAM_VOICE_CALL, state)
    }

    /**
     * 设置系统声音静音状态
     * @param state `true` 静音, `false` 非静音
     * @return `true` success, `false` fail
     */
    fun setStreamMuteBySystem(state: Boolean): Boolean {
        return setStreamMute(AudioManager.STREAM_SYSTEM, state)
    }

    /**
     * 设置来电响铃静音状态
     * @param state `true` 静音, `false` 非静音
     * @return `true` success, `false` fail
     */
    fun setStreamMuteByRing(state: Boolean): Boolean {
        return setStreamMute(AudioManager.STREAM_RING, state)
    }

    /**
     * 设置闹钟声音静音状态
     * @param state `true` 静音, `false` 非静音
     * @return `true` success, `false` fail
     */
    fun setStreamMuteByAlarm(state: Boolean): Boolean {
        return setStreamMute(AudioManager.STREAM_ALARM, state)
    }

    /**
     * 设置通知声音静音状态
     * @param state `true` 静音, `false` 非静音
     * @return `true` success, `false` fail
     */
    fun setStreamMuteByNotification(state: Boolean): Boolean {
        return setStreamMute(AudioManager.STREAM_NOTIFICATION, state)
    }

    /**
     * 设置指定声音流静音状态
     * @param streamType 流类型
     * @param state      `true` 静音, `false` 非静音
     * @return `true` success, `false` fail
     */
    fun setStreamMute(
        streamType: Int,
        state: Boolean
    ): Boolean {
        try {
            application.audioManager.setStreamMute(streamType, state)
             return true
        } catch (e: Exception) {
               Timber.d( e, "setStreamMute")
        }
        return false
    }

    // =======
    // = 模式 =
    // =======
    /**
     * 获取当前的音频模式
     * <pre>
     * 返回值有下述几种模式:
     * MODE_NORMAL( 普通 )
     * MODE_RINGTONE( 铃声 )
     * MODE_IN_CALL( 打电话 )
     * MODE_IN_COMMUNICATION( 通话 )
    </pre> *
     * @return 当前的音频模式
     */
    fun getMode(): Int {
            try {
                return application.audioManager.mode
            } catch (e: java.lang.Exception) {
                Timber.d( e, "getMode")
            }
        return AudioManager.MODE_NORMAL
    }

    /**
     * 设置当前的音频模式
     * <pre>
     * 有下述几种模式:
     * MODE_NORMAL( 普通 )
     * MODE_RINGTONE( 铃声 )
     * MODE_IN_CALL( 打电话 )
     * MODE_IN_COMMUNICATION( 通话 )
    </pre> *
     * @param mode 音频模式
     * @return `true` success, `false` fail
     */
    fun setMode(mode: Int): Boolean {
            try {
                application.audioManager.mode = mode
                return true
            } catch (e: java.lang.Exception) {
                Timber.d( e, "setMode")
            }
        return false
    }

    // ==========
    // = 铃声模式 =
    // ==========
    /**
     * 获取当前的铃声模式
     * <pre>
     * 返回值有下述几种模式:
     * RINGER_MODE_NORMAL( 普通 )
     * RINGER_MODE_SILENT( 静音 )
     * RINGER_MODE_VIBRATE( 震动 )
    </pre> *
     * @return 当前的铃声模式
     */
    fun getRingerMode(): Int {
            try {
                return application.audioManager.ringerMode
            } catch (e: java.lang.Exception) {
                Timber.d( e, "getRingerMode")
            }
        return AudioManager.RINGER_MODE_NORMAL
    }

    /**
     * 获取当前的铃声模式
     * @param ringerMode 铃声模式
     * @return `true` success, `false` fail
     */
    fun setRingerMode(ringerMode: Int): Boolean {
        return setRingerMode(ringerMode, true)
    }

    /**
     * 获取当前的铃声模式
     * <pre>
     * 有下述几种模式:
     * RINGER_MODE_NORMAL( 普通 )
     * RINGER_MODE_SILENT( 静音 )
     * RINGER_MODE_VIBRATE( 震动 )
    </pre> *
     * @param ringerMode 铃声模式
     * @param setting    如果没授权, 是否跳转到设置页面
     * @return `true` success, `false` fail
     */
    fun setRingerMode(
        ringerMode: Int,
        setting: Boolean
    ): Boolean {
        try {
             if (isDoNotDisturb(setting)) {
               application.audioManager.ringerMode = ringerMode
               return true
             }
        } catch (e: java.lang.Exception) {
             Timber.d( e, "setRingerMode")
         }
        return false
    }

    /**
     * 判断是否授权 Do not disturb 权限
     * <pre>
     * 授权 Do not disturb 权限, 才可进行音量操作
    </pre> *
     * @param setting 如果没授权, 是否跳转到设置页面
     * @return `true` yes, `false` no
     */
    fun isDoNotDisturb(setting: Boolean): Boolean {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && !notificationManager.isNotificationPolicyAccessGranted) {
                if (setting) {
                    val intent = Intent(
                        Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS
                    )
                    intent.startForActivity(application)
                }
            } else {
                return true
            }
        } catch (e: java.lang.Exception) {
            Timber.d( e, "isDoNotDisturb")
        }
        return false
    }

    // =
    /**
     * 设置静音模式 ( 静音, 且无振动 )
     * @return `true` success, `false` fail
     */
    fun ringerSilent(): Boolean {
        return setRingerMode(AudioManager.RINGER_MODE_SILENT)
    }

    /**
     * 设置震动模式 ( 静音, 但有振动 )
     * @return `true` success, `false` fail
     */
    fun ringerVibrate(): Boolean {
        return setRingerMode(AudioManager.RINGER_MODE_VIBRATE)
    }

    /**
     * 设置正常模式 ( 正常声音, 振动开关由 setVibrateSetting 决定 )
     * @return `true` success, `false` fail
     */
    fun ringerNormal(): Boolean {
        return setRingerMode(AudioManager.RINGER_MODE_NORMAL)
    }


    /**
     * 设置是否打开扩音器 ( 扬声器 )
     * @param on `true` yes, `false` no
     * @return `true` success, `false` fail
     */
    fun setSpeakerphoneOn(on: Boolean): Boolean {
            try {
                application.audioManager.isSpeakerphoneOn = on
                return true
            } catch (e: java.lang.Exception) {
                Timber.d( e, "setSpeakerphoneOn")
            }
        return false
    }

    /**
     * 设置是否让麦克风静音
     * @param on `true` yes, `false` no
     * @return `true` success, `false` fail
     */
    fun setMicrophoneMute(on: Boolean): Boolean {
            try {
                application.audioManager.isMicrophoneMute = on
                return true
            } catch (e: java.lang.Exception) {
                Timber.d( e, "setMicrophoneMute")
            }
        return false
    }

    /**
     * 判断是否打开扩音器 ( 扬声器 )
     * @return `true` yes, `false` no
     */
    fun isSpeakerphoneOn(): Boolean {

            try {
                return application.audioManager.isSpeakerphoneOn
            } catch (e: java.lang.Exception) {
                Timber.d( e, "isSpeakerphoneOn")
            }

        return false
    }

    /**
     * 判断麦克风是否静音
     * @return `true` yes, `false` no
     */
    fun isMicrophoneMute(): Boolean {
            try {
                return application.audioManager.isMicrophoneMute
            } catch (e: java.lang.Exception) {
                Timber.d( e, "isMicrophoneMute")
            }
        return false
    }

    /**
     * 判断是否有音乐处于活跃状态
     * @return `true` yes, `false` no
     */
    fun isMusicActive(): Boolean {
            try {
                return application.audioManager.isMusicActive
            } catch (e: java.lang.Exception) {
                Timber.d( e, "isMusicActive")
            }
        return false
    }

    /**
     * 判断是否插入了耳机
     * @return `true` yes, `false` no
     */
    fun isWiredHeadsetOn(): Boolean {
            try {
                return application.audioManager.isWiredHeadsetOn
            } catch (e: java.lang.Exception) {
                Timber.d( e, "isWiredHeadsetOn")
            }
        return false
    }

    /**
     * 检查蓝牙 A2DP 音频外设是否已连接
     * @return `true` yes, `false` no
     */
    fun isBluetoothA2dpOn(): Boolean {
            try {
                return application.audioManager.isBluetoothA2dpOn
            } catch (e: java.lang.Exception) {
                Timber.d( e, "isBluetoothA2dpOn")
            }
        return false
    }

    /**
     * 检查当前平台是否支持使用 SCO 的关闭调用用例
     * @return `true` yes, `false` no
     */
    fun isBluetoothScoAvailableOffCall(): Boolean {
            try {
                return application.audioManager.isBluetoothScoAvailableOffCall
            } catch (e: java.lang.Exception) {
                Timber.d( e, "isBluetoothScoAvailableOffCall")
            }
        return false
    }

    /**
     * 检查通信是否使用蓝牙 SCO
     * @return `true` yes, `false` no
     */
    fun isBluetoothScoOn(): Boolean {
            try {
                return application.audioManager.isBluetoothScoOn
            } catch (e: java.lang.Exception) {
                Timber.d( e, "isBluetoothScoOn")
            }

        return false
    }

    /**
     * 设置是否使用蓝牙 SCO 耳机进行通讯
     * @param on `true` yes, `false` no
     * @return `true` success, `false` fail
     */
    fun setBluetoothScoOn(on: Boolean): Boolean {
            try {
                application.audioManager.isBluetoothScoOn = on
                return true
            } catch (e: java.lang.Exception) {
                Timber.d( e, "setBluetoothScoOn")
            }
        return false
    }

    /**
     * 启动蓝牙 SCO 音频连接
     * @return `true` success, `false` fail
     */
    fun startBluetoothSco(): Boolean {
            try {
                application.audioManager.startBluetoothSco()
                return true
            } catch (e: java.lang.Exception) {
                Timber.d( e, "startBluetoothSco")
            }
        return false
    }

    /**
     * 停止蓝牙 SCO 音频连接
     * @return `true` success, `false` fail
     */
    fun stopBluetoothSco(): Boolean {
            try {
                application.audioManager.stopBluetoothSco()
                return true
            } catch (e: java.lang.Exception) {
                Timber.d( e, "stopBluetoothSco")
            }
        return false
    }

    // =

    // =
    /**
     * 加载音效
     * @return `true` success, `false` fail
     */
    fun loadSoundEffects(): Boolean {
            try {
                application.audioManager.loadSoundEffects()
                return true
            } catch (e: java.lang.Exception) {
                Timber.d( e, "loadSoundEffects")
            }

        return false
    }

    /**
     * 卸载音效
     * @return `true` success, `false` fail
     */
    fun unloadSoundEffects(): Boolean {
       

            try {
                application.audioManager.unloadSoundEffects()
                return true
            } catch (e: java.lang.Exception) {
                Timber.d( e, "unloadSoundEffects")
            }

        return false
    }

    /**
     * 播放音效
     * @param effectType [AudioManager.FX_KEY_CLICK],
     * [AudioManager.FX_FOCUS_NAVIGATION_UP],
     * [AudioManager.FX_FOCUS_NAVIGATION_DOWN],
     * [AudioManager.FX_FOCUS_NAVIGATION_LEFT],
     * [AudioManager.FX_FOCUS_NAVIGATION_RIGHT],
     * [AudioManager.FX_KEYPRESS_STANDARD],
     * [AudioManager.FX_KEYPRESS_SPACEBAR],
     * [AudioManager.FX_KEYPRESS_DELETE],
     * [AudioManager.FX_KEYPRESS_RETURN],
     * [AudioManager.FX_KEYPRESS_INVALID],
     * @param volume     音量大小
     * @return `true` success, `false` fail
     */
    fun playSoundEffect(
        effectType: Int,
        volume: Float
    ): Boolean {

            try {
                application.audioManager.playSoundEffect(effectType, volume)
                return true
            } catch (e: java.lang.Exception) {
                Timber.d( e, "playSoundEffect")
            }

        return false
    }

    // =

    // =
    /**
     * 放弃音频焦点, 使上一个焦点所有者 ( 如果有 ) 接收焦点
     * @param listener 焦点监听事件
     * @return `true` success, `false` fail
     */
    fun abandonAudioFocus(listener: OnAudioFocusChangeListener?): Boolean {
       

            try {
                application.audioManager.abandonAudioFocus(listener)
                return true
            } catch (e: java.lang.Exception) {
                Timber.d( e, "abandonAudioFocus")
            }

        return false
    }

    /**
     * 调整最相关的流的音量, 或者给定的回退流
     * @param direction 调整参数
     * @return `true` success, `false` fail
     */
    fun adjustSuggestedStreamVolume(direction: Int): Boolean {
       

            try {
                application.audioManager.adjustSuggestedStreamVolume(
                    direction, AudioManager.USE_DEFAULT_STREAM_TYPE, 0
                )
                return true
            } catch (e: java.lang.Exception) {
                Timber.d( e, "adjustSuggestedStreamVolume")
            }

        return false
    }

    /**
     * 获取音频硬件指定 key 的参数值
     * @param keys Key
     * @return 音频硬件指定 key 的参数值
     */
    fun getParameters(keys: String?): String? {

            try {
                return application.audioManager.getParameters(keys)
            } catch (e: java.lang.Exception) {
                Timber.d( e, "getParameters")
            }

        return null
    }

    /**
     * 获取用户对振动类型的振动设置
     * @param vibrateType [AudioManager.VIBRATE_TYPE_NOTIFICATION] or [AudioManager.VIBRATE_TYPE_RINGER]
     * @return [AudioManager.VIBRATE_SETTING_ON], [AudioManager.VIBRATE_SETTING_OFF], [AudioManager.VIBRATE_SETTING_ONLY_SILENT]
     */
    fun getVibrateSetting(vibrateType: Int): Int {
        try {
                return application.audioManager.getVibrateSetting(vibrateType)
            } catch (e: java.lang.Exception) {
                Timber.d( e, "getVibrateSetting")
         }
        return -1
    }

}

val globalAudioManager:AudioManager by lazy { application.audioManager }

val Context.audioManager:AudioManager
    get() = getSystemService(Context.AUDIO_SERVICE) as AudioManager